package mt.client;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.MenuBar;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JMenuBar;
import javax.swing.JPopupMenu;

import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JButton;
import javax.swing.JTextField;

import mt.*;
import mt.comm.ClientComm;
import mt.dummy.ClientCommDummy;

import java.awt.FlowLayout;

import javax.swing.JLabel;
import javax.swing.JTextPane;

import java.awt.GridLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JScrollPane;
import javax.swing.JScrollBar;
import javax.swing.JTextArea;
import javax.swing.JTable;
import javax.swing.border.LineBorder;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Vector;

import javax.swing.JList;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class ClientGUI extends JFrame implements MicroTraderClient {
	public JTextField txtQuantity;
	public OrderResume orderResume;
	public ClientComm client;
	public JList listPaneSell;
	private JList listPaneBuy;
	JList listPaneStockDetails;
	public DefaultListModel listModelBuy;
	public DefaultListModel listModelSell;
	public DefaultListModel listModelDetails;

	public static final int ONE = 1;
	public static final int ZERO = 0;
	/**
	 * Launch the application.
	 */

    ListDataListener listDataListener = new ListDataListener() {
        public void contentsChanged(ListDataEvent listDataEvent) {
          appendEvent(listDataEvent);
        }

        public void intervalAdded(ListDataEvent listDataEvent) {
          appendEvent(listDataEvent);
        }

        public void intervalRemoved(ListDataEvent listDataEvent) {
          appendEvent(listDataEvent);
        }

        private void appendEvent(ListDataEvent listDataEvent) {
          switch (listDataEvent.getType()) {
          case ListDataEvent.CONTENTS_CHANGED:
            System.out.println("Type: Contents Changed");
            break;
          case ListDataEvent.INTERVAL_ADDED:
            System.out.println("Type: Interval Added");
            break;
          case ListDataEvent.INTERVAL_REMOVED:
            System.out.println("Type: Interval Removed");
            break;
          }
          System.out.println(", Index0: " + listDataEvent.getIndex0());
          System.out.println(", Index1: " + listDataEvent.getIndex1());
          DefaultListModel theModel = (DefaultListModel) listDataEvent.getSource();
          System.out.println(theModel);
        }
      };
	/**
	 * Create the frame.
	 */
	public ClientGUI() {
		this.orderResume = new OrderResume();
		this.client = new ClientCommDummy();

		listModelBuy = new DefaultListModel();
		listModelSell = new DefaultListModel();
		listModelDetails = new DefaultListModel();;
		
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 689, 546);

		
		// MENU BAR

		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
			// CONNECTIVITY
		JMenu mnConnectivity = new JMenu("Connectivity");
		menuBar.add(mnConnectivity);
				// FIND SERVERS
		JMenuItem mntmdFindServers = new JMenuItem("Find Servers");
		mnConnectivity.add(mntmdFindServers);
				// DISCONNECT
		JMenuItem mntmDisconnect = new JMenuItem("Disconnect");
		mnConnectivity.add(mntmDisconnect);
			// PROFILE
		JMenu mnProfile = new JMenu("Profile");
		menuBar.add(mnProfile);
				// ORDER HISTORY
		JMenuItem mntmOrderHistory = new JMenuItem("Order History");
		mnProfile.add(mntmOrderHistory);

		
		
		
		// DISPLAY

		JPanel panelDisplay = new JPanel();
		getContentPane().add(panelDisplay, BorderLayout.CENTER);
		panelDisplay.setLayout(new GridLayout(0, 1, 0, 0));
		
			// SELL

		JPanel panelSell = new JPanel();
		panelDisplay.add(panelSell);
		panelSell.setLayout(new BorderLayout(0, 0));
				// LABEL
		JLabel lblSell = new JLabel("Sell");
		lblSell.setHorizontalAlignment(JLabel.CENTER);
		panelSell.add(lblSell, BorderLayout.NORTH);
				// LISTA
		listPaneSell = new JList(listModelSell);
		JScrollPane scrollPaneSell = new JScrollPane(listPaneSell);
		panelSell.add(scrollPaneSell, BorderLayout.CENTER);
		
			// BUY

		JPanel panelBuy = new JPanel();
		panelDisplay.add(panelBuy);
		panelBuy.setLayout(new BorderLayout(0, 0));
				// LABEL
		JLabel lblBuy = new JLabel("Buy");
		lblBuy.setHorizontalAlignment(JLabel.CENTER);
		panelBuy.add(lblBuy, BorderLayout.NORTH);
				// LISTA
		listPaneBuy = new JList(listModelBuy);
		JScrollPane scrollPaneBuy = new JScrollPane(listPaneBuy);
		panelBuy.add(scrollPaneBuy, BorderLayout.CENTER);
		
		
		// STOCK DETAILS PANEL
		
		JPanel panelStockDetails = new JPanel();
		getContentPane().add(panelStockDetails, BorderLayout.EAST);
		panelStockDetails.setLayout(new BorderLayout(0, 0));

		JLabel lblStockDetails = new JLabel("Stock Details");
		panelStockDetails.add(lblStockDetails, BorderLayout.NORTH);

		listPaneStockDetails = new JList(listModelDetails);
		JScrollPane scrollPaneStockDetails = new JScrollPane(listPaneStockDetails);
		panelStockDetails.add(scrollPaneStockDetails, BorderLayout.CENTER);
		
		
		
		listPaneBuy.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if(listPaneBuy.getSelectedValue()!=null) {
					listModelDetails.removeAllElements();
					listModelDetails.addElement("NickName: "+((Order)listPaneBuy.getSelectedValue()).getNickname());
					listModelDetails.addElement("Units: "+((Order)listPaneBuy.getSelectedValue()).getNumberOfUnits());
					listModelDetails.addElement("Price: "+((Order)listPaneBuy.getSelectedValue()).getPricePerUnit());
					listModelDetails.addElement("Stock: "+((Order)listPaneBuy.getSelectedValue()).getStock());
					listModelDetails.addElement("Server: "+((Order)listPaneBuy.getSelectedValue()).getServerOrderID());
					}
					else {
						System.out.println("No object selected to place the order.");
						}
			}
		
		});
		

		
		
		
		listPaneSell.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if(listPaneSell.getSelectedValue()!=null) {
					listModelDetails.removeAllElements();
					listModelDetails.addElement("NickName: "+((Order)listPaneSell.getSelectedValue()).getNickname());
					listModelDetails.addElement("Units: "+((Order)listPaneSell.getSelectedValue()).getNumberOfUnits());
					listModelDetails.addElement("Price: "+((Order)listPaneSell.getSelectedValue()).getPricePerUnit());
					listModelDetails.addElement("Stock: "+((Order)listPaneSell.getSelectedValue()).getStock());
					listModelDetails.addElement("Server: "+((Order)listPaneSell.getSelectedValue()).getServerOrderID());
					
					
				
					}
					else {
						System.out.println("No object selected to place the order.");
						}
			}

			
		});
		
		
		

		
		// CONTROLS

		JPanel panelControl = new JPanel();
		getContentPane().add(panelControl, BorderLayout.SOUTH);
		panelControl.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		JButton btnPlaceOrder = new JButton("Place Order");
		btnPlaceOrder.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				try{
				Order selectedOrder = (Order)listPaneSell.getSelectedValue();
				int buyQuantity = Integer.parseInt(txtQuantity.getText().trim()) ;
				if(buyQuantity == 0 || selectedOrder == null){
					listModelDetails.removeAllElements();
					listModelDetails.addElement("Please introduce the number of orders");
					listModelDetails.addElement(", greater than zero");
					listModelDetails.addElement(", and select a stock");
					return;
				
					
				}
				
				if(selectedOrder!=null) {
		
					if(selectedOrder.getNumberOfUnits() > ZERO  && buyQuantity <= selectedOrder.getNumberOfUnits()  ){
						selectedOrder.setNumberOfUnits(selectedOrder.getNumberOfUnits()-buyQuantity);
						listModelDetails.removeAllElements();
						listModelDetails.addElement("NickName: "+selectedOrder.getNickname());
						listModelDetails.addElement("Units: "+selectedOrder.getNumberOfUnits());
						listModelDetails.addElement("Price: "+selectedOrder.getPricePerUnit());
						listModelDetails.addElement("Stock: "+selectedOrder.getStock());
						listModelDetails.addElement("Server: "+selectedOrder.getServerOrderID());
						if(selectedOrder.getNumberOfUnits() == ZERO){
							listModelSell.removeElement(selectedOrder);
							
						}
						
					}
				
					else if(buyQuantity > selectedOrder.getNumberOfUnits()){
						
						listModelDetails.removeAllElements();
						listModelDetails.addElement("There is not enough stock");
						listModelDetails.addElement(", please select less quantity");
						return;
					}
					else{
						listModelSell.removeElement(selectedOrder);
						
					}
					
					boolean exists = false;
					for(int index = ZERO; index < listModelBuy.size(); index ++){
						Order buyOrder = (Order)listModelBuy.getElementAt(index);
						
						if(buyOrder.getStock().equals(selectedOrder.getStock())){
						buyOrder.setNumberOfUnits(buyOrder.getNumberOfUnits()+buyQuantity);
						exists = true;
						
						
						break;
							
						}
					}
						
					
					if(!exists){
						listModelBuy.addElement(Order.createSellOrder(selectedOrder.getNickname(),//
								selectedOrder.getStock(),//
								buyQuantity,//
								selectedOrder.getPricePerUnit()) );
					}
				
				
					}
			}
				catch(NumberFormatException exc){
					listModelDetails.removeAllElements();
					listModelDetails.addElement("Please introduce the number of orders");
					listModelDetails.addElement(", greater than zero");
					
				}
			}
		
		});
		panelControl.add(btnPlaceOrder);

		txtQuantity = new JTextField();
		txtQuantity.setText("Quantity");
		panelControl.add(txtQuantity);
		listModelBuy.addListDataListener(listDataListener);

	}


	
	@Override
	public void start(ClientComm clientComm) {
		this.client = clientComm;

		for(Order order : this.orderResume.getBuyOrders()){
			listModelBuy.addElement(order);
		}
		
		System.out.println(this.orderResume.getSellOrders().size());
		
		for(Order order : this.orderResume.getSellOrders()){
			listModelSell.addElement(order);
		}
		
		
		
		

	}

	public JTextField getTxtQuantity() {
		return txtQuantity;
	}

	public void setTxtQuantity(JTextField txtQuantity) {
		this.txtQuantity = txtQuantity;
	}

	public OrderResume getOrderResume() {
		return orderResume;
	}

	public void setOrderResume(OrderResume orderResume) {
		this.orderResume = orderResume;
	}


	public ClientComm getClient() {
		return client;
	}

	public void setClient(ClientComm client) {
		this.client = client;
	}

	public JList getListPaneSell() {
		return listPaneSell;
	}

	public void setListPaneSell(JList listPaneSell) {
		this.listPaneSell = listPaneSell;
	}

	public JList getListPaneBuy() {
		return listPaneBuy;
	}

	public void setListPaneBuy(JList listPaneBuy) {
		this.listPaneBuy = listPaneBuy;
	}
}
